Rework color translation to support gray scale and bitmaps
authorKristian Rietveld <kris@gtk.org>
Sat, 26 Jun 2010 15:08:15 +0000 (17:08 +0200)
committerKristian Rietveld <kris@gtk.org>
Sun, 27 Jun 2010 08:59:46 +0000 (10:59 +0200)
(cherry picked from commit 49f72c1fb4bf90fde0ba9c4b40794672b775d2a8)

gdk/quartz/gdkcolor-quartz.c
gdk/quartz/gdkgc-quartz.c
gdk/quartz/gdkprivate-quartz.h
gdk/quartz/gdkwindow-quartz.c

index b722185792497495756b8fbf3d9c74e93ae1fb8e..7afcf2cce5621fd367a091657cfc0f3872dc9ab6 100644 (file)
@@ -163,20 +163,46 @@ gdk_colormap_get_screen (GdkColormap *cmap)
   return gdk_screen_get_default ();
 }
 
-void
-_gdk_quartz_colormap_get_rgba_from_pixel (GdkColormap *colormap,
-                                         guint32      pixel,
-                                         CGFloat      *red,
-                                         CGFloat      *green,
-                                         CGFloat      *blue,
-                                         CGFloat      *alpha)
+CGColorRef
+_gdk_quartz_colormap_get_cgcolor_from_pixel (GdkDrawable *drawable,
+                                             guint32      pixel)
 {
-  *red   = (pixel >> 16 & 0xff) / 255.0;
-  *green = (pixel >> 8  & 0xff) / 255.0;
-  *blue  = (pixel       & 0xff) / 255.0;
-  if (colormap && gdk_colormap_get_visual (colormap)->depth == 32)
-    *alpha = (pixel >> 24 & 0xff) / 255.0;
+  CGFloat r, g, b, a;
+  CGColorRef color;
+  const GdkVisual *visual;
+  GdkColormap *colormap;
+
+  colormap = gdk_drawable_get_colormap (drawable);
+  if (colormap)
+    visual = gdk_colormap_get_visual (colormap);
   else
-    *alpha = 1.0;
+    visual = gdk_visual_get_best_with_depth (gdk_drawable_get_depth (drawable));
+
+  switch (visual->type)
+    {
+      case GDK_VISUAL_STATIC_GRAY:
+      case GDK_VISUAL_GRAYSCALE:
+        g = (pixel & 0xff) / 255.0f;
+
+        if (visual->depth == 1)
+          g = g == 0.0f ? 0.0f : 1.0f;
+
+        color = CGColorCreateGenericGray (g, 1.0f);
+        break;
+
+      default:
+        r = (pixel >> 16 & 0xff) / 255.0;
+        g = (pixel >> 8  & 0xff) / 255.0;
+        b = (pixel       & 0xff) / 255.0;
+
+        if (visual->depth == 32)
+          a = (pixel >> 24 & 0xff) / 255.0;
+        else
+          a = 1.0;
+
+        color = CGColorCreateGenericRGB (r, g, b, a);
+        break;
+    }
+
+  return color;
 }
index d0a23668fc4fb10c958e4728c0b37799cd7f2c62..780732be0ece078f14698fbfcbd157915a10c206 100644 (file)
@@ -280,11 +280,24 @@ gdk_gc_get_screen (GdkGC *gc)
   return _gdk_screen;
 }
 
+struct PatternCallbackInfo
+{
+  GdkGCQuartz *private_gc;
+  GdkDrawable *drawable;
+};
+
+static void
+pattern_callback_info_release (void *info)
+{
+  g_free (info);
+}
+
 static void
 gdk_quartz_draw_tiled_pattern (void         *info,
                               CGContextRef  context)
 {
-  GdkGC       *gc = GDK_GC (info);
+  struct PatternCallbackInfo *pinfo = info;
+  GdkGC       *gc = GDK_GC (pinfo->private_gc);
   CGImageRef   pattern_image;
   size_t       width, height;
 
@@ -302,10 +315,11 @@ static void
 gdk_quartz_draw_stippled_pattern (void         *info,
                                  CGContextRef  context)
 {
-  GdkGC      *gc = GDK_GC (info);
+  struct PatternCallbackInfo *pinfo = info;
+  GdkGC      *gc = GDK_GC (pinfo->private_gc);
   CGImageRef  pattern_image;
   CGRect      rect;
-  CGFloat     r, g, b, a;
+  CGColorRef  color;
 
   pattern_image = GDK_PIXMAP_IMPL_QUARTZ (GDK_PIXMAP_OBJECT (_gdk_gc_get_stipple (gc))->impl)->image;
   rect = CGRectMake (0, 0,
@@ -313,10 +327,11 @@ gdk_quartz_draw_stippled_pattern (void         *info,
                     CGImageGetHeight (pattern_image));
 
   CGContextClipToMask (context, rect, pattern_image);
-  _gdk_quartz_colormap_get_rgba_from_pixel (gc->colormap, 
-                                           _gdk_gc_get_fg_pixel (gc),
-                                           &r, &g, &b, &a);
-  CGContextSetRGBFillColor (context, r, g, b, a);
+  color = _gdk_quartz_colormap_get_cgcolor_from_pixel (pinfo->drawable,
+                                                       _gdk_gc_get_fg_pixel (gc));
+  CGContextSetFillColorWithColor (context, color);
+  CGColorRelease (color);
+
   CGContextFillRect (context, rect);
 }
 
@@ -324,27 +339,30 @@ static void
 gdk_quartz_draw_opaque_stippled_pattern (void         *info,
                                         CGContextRef  context)
 {
-  GdkGC      *gc = GDK_GC (info);
+  struct PatternCallbackInfo *pinfo = info;
+  GdkGC      *gc = GDK_GC (pinfo->private_gc);
   CGImageRef  pattern_image;
   CGRect      rect;
-  CGFloat     r, g, b, a;
+  CGColorRef  color;
 
   pattern_image = GDK_PIXMAP_IMPL_QUARTZ (GDK_PIXMAP_OBJECT (_gdk_gc_get_stipple (gc))->impl)->image;
   rect = CGRectMake (0, 0,
                     CGImageGetWidth (pattern_image),
                     CGImageGetHeight (pattern_image));
 
-  _gdk_quartz_colormap_get_rgba_from_pixel (gc->colormap, 
-                                           _gdk_gc_get_bg_pixel (gc),
-                                           &r, &g, &b, &a);
-  CGContextSetRGBFillColor (context, r, g, b, a);
+  color = _gdk_quartz_colormap_get_cgcolor_from_pixel (pinfo->drawable,
+                                                       _gdk_gc_get_bg_pixel (gc));
+  CGContextSetFillColorWithColor (context, color);
+  CGColorRelease (color);
+
   CGContextFillRect (context, rect);
 
   CGContextClipToMask (context, rect, pattern_image);
-  _gdk_quartz_colormap_get_rgba_from_pixel (gc->colormap, 
-                                           _gdk_gc_get_fg_pixel (gc),
-                                           &r, &g, &b, &a);
-  CGContextSetRGBFillColor (context, r, g, b, a);
+  color = _gdk_quartz_colormap_get_cgcolor_from_pixel (info,
+                                                       _gdk_gc_get_fg_pixel (gc));
+  CGContextSetFillColorWithColor (context, color);
+  CGColorRelease (color);
+
   CGContextFillRect (context, rect);
 }
 
@@ -453,12 +471,12 @@ _gdk_quartz_gc_update_cg_context (GdkGC                      *gc,
     {
       CGLineCap  line_cap  = kCGLineCapButt;
       CGLineJoin line_join = kCGLineJoinMiter;
-      CGFloat    r, g, b, a;
+      CGColorRef color;
 
-      _gdk_quartz_colormap_get_rgba_from_pixel (gc->colormap, 
-                                               fg_pixel,
-                                               &r, &g, &b, &a);
-      CGContextSetRGBStrokeColor (context, r, g, b, a);
+      color = _gdk_quartz_colormap_get_cgcolor_from_pixel (drawable,
+                                                           fg_pixel);
+      CGContextSetStrokeColorWithColor (context, color);
+      CGColorRelease (color);
 
       CGContextSetLineWidth (context, MAX (G_MINFLOAT, private->line_width));
 
@@ -516,15 +534,15 @@ _gdk_quartz_gc_update_cg_context (GdkGC                      *gc,
       CGColorSpaceRef baseSpace;
       CGColorSpaceRef patternSpace;
       CGFloat         alpha     = 1.0;
-      CGFloat         colors[4] = { 0.0, 0.0, 0.0, 0.0 };
-      CGFloat         r, g, b, a;
 
       if (fill == GDK_SOLID)
        {
-         _gdk_quartz_colormap_get_rgba_from_pixel (gc->colormap, 
-                                                   fg_pixel,
-                                                   &r, &g, &b, &a);
-         CGContextSetRGBFillColor (context, r, g, b, a);
+          CGColorRef color;
+
+         color = _gdk_quartz_colormap_get_cgcolor_from_pixel (drawable,
+                                                               fg_pixel);
+         CGContextSetFillColorWithColor (context, color);
+          CGColorRelease (color);
        }
       else
        {
@@ -534,8 +552,16 @@ _gdk_quartz_gc_update_cg_context (GdkGC                      *gc,
              gfloat     width, height;
              gboolean   is_colored = FALSE;
              CGPatternCallbacks callbacks =  { 0, NULL, NULL };
+              struct PatternCallbackInfo *info;
              CGPoint    phase;
 
+              info = g_new (struct PatternCallbackInfo, 1);
+              /* Won't ref to avoid circular dependencies */
+              info->drawable = drawable;
+              info->private_gc = private;
+
+              callbacks.releaseInfo = pattern_callback_info_release;
+
              switch (fill)
                {
                case GDK_TILED:
@@ -563,7 +589,7 @@ _gdk_quartz_gc_update_cg_context (GdkGC                      *gc,
              phase = CGPointApplyAffineTransform (CGPointMake (gc->ts_x_origin, gc->ts_y_origin), CGContextGetCTM (context));
              CGContextSetPatternPhase (context, CGSizeMake (phase.x, phase.y));
 
-             private->ts_pattern = CGPatternCreate (private,
+             private->ts_pattern = CGPatternCreate (info,
                                                     CGRectMake (0, 0, width, height),
                                                     CGAffineTransformIdentity,
                                                     width, height,
@@ -580,12 +606,20 @@ _gdk_quartz_gc_update_cg_context (GdkGC                      *gc,
          CGColorSpaceRelease (baseSpace);
 
          if (fill == GDK_STIPPLED)
-           _gdk_quartz_colormap_get_rgba_from_pixel (gc->colormap, fg_pixel,
-                                                     &colors[0], &colors[1],
-                                                     &colors[2], &colors[3]);
-
-         CGContextSetFillPattern (context, private->ts_pattern,
-                                  (fill == GDK_STIPPLED) ? colors : &alpha);
+            {
+              CGColorRef color;
+              const CGFloat *components;
+
+              color = _gdk_quartz_colormap_get_cgcolor_from_pixel (drawable,
+                                                                   fg_pixel);
+              components = CGColorGetComponents (color);
+
+              CGContextSetFillPattern (context, private->ts_pattern,
+                                       components);
+              CGColorRelease (color);
+            }
+          else
+            CGContextSetFillPattern (context, private->ts_pattern, &alpha);
        }
     }
 
index 0809dcf82b0e445f7fbd500ed12096e4a2475c16..8e9708f3c4d8b9c2106bb63b368ed3a29584f2f1 100644 (file)
@@ -129,12 +129,8 @@ void   _gdk_quartz_gc_update_cg_context (GdkGC                      *gc,
                                         GdkQuartzContextValuesMask  mask);
 
 /* Colormap */
-void _gdk_quartz_colormap_get_rgba_from_pixel (GdkColormap *colormap,
-                                              guint32      pixel,
-                                              CGFloat     *red,
-                                              CGFloat     *green,
-                                              CGFloat     *blue,
-                                              CGFloat     *alpha);
+CGColorRef _gdk_quartz_colormap_get_cgcolor_from_pixel (GdkDrawable *drawable,
+                                                        guint32      pixel);
 
 /* Window */
 gboolean    _gdk_quartz_window_is_ancestor          (GdkWindow *ancestor,
index efc0672e7c1b9f7198a5b68e609c84f3f2567dfa..8de986c52d51c1f1737064198ff04aa7797d7bb5 100644 (file)
@@ -262,14 +262,14 @@ gdk_window_impl_quartz_begin_paint_region (GdkPaintable    *paintable,
   if (bg_pixmap == NULL)
     {
       CGContextRef cg_context;
-      CGFloat r, g, b, a;
+      CGColorRef color;
       gint i;
 
       cg_context = gdk_quartz_drawable_get_context (GDK_DRAWABLE (impl), FALSE);
-      _gdk_quartz_colormap_get_rgba_from_pixel (gdk_drawable_get_colormap (window),
-                                                private->bg_color.pixel,
-                                                &r, &g, &b, &a);
-      CGContextSetRGBFillColor (cg_context, r, g, b, a);
+      color = _gdk_quartz_colormap_get_cgcolor_from_pixel (window,
+                                                           private->bg_color.pixel);
+      CGContextSetFillColorWithColor (cg_context, color);
+      CGColorRelease (color);
  
       for (i = 0; i < n_rects; i++)
         {